import pygame
from pygame.sprite import Group
from PyPixelCore.Setting import *
from PyPixelCore.group.BaseGroup import BaseGroup
from PyPixelCore.timer.CycleTimer import CycleTimer

from PyPixelCore.Setting import layers


def base_collision_func(self):
    print("碰撞")


"""
    管理所有精灵块组
    核心:
    all_sprites: 所有的记录精灵
    collision_sprites: 所有能够碰撞的精灵
    layer_draw_sprites: 根据层绘制精灵
    collision_sprites: 碰撞检测组
    click_able_sprites: 支持点击事件的精灵
    focus_able_sprites: 支持焦点事件的精灵
    public_timer_dict: 公共的计时器
"""


class GroupsManager:
    def __init__(self):
        self.all_sprites = BaseGroup()  # 所有的精灵块(最重要的)

        # 从所有精灵块中解析出需要被绘制的方块
        self.layer_draw_sprites = []  # 用于绘制精灵
        for i in range(len(layers)):
            self.layer_draw_sprites.append(BaseGroup())

        # 公共计时器  dict{timer_name: [timer, sprite_group]}
        self.public_timer_dict = {}
        self.set_public_timer(public_timer_dict)

        # 碰撞精灵块组 只在里面碰撞,节省性能
        self.collision_sprites = BaseGroup()

        # 点击精灵组 只在里面检测点击,节省性能
        self.click_able_sprites = BaseGroup()

        # 焦点精灵组 只在里面寻找焦点,节省性能
        self.focus_able_sprites = BaseGroup()

        # # 控件组(按钮等交互式控件)
        # self.control_sprites = BaseGroup()

        # func

        # self.blit_static_sprites = BaseGroup()  # 静态的图片块
        # self.blit_dynamic_sprites = BaseGroup()  # 动态的图片块

    def set_public_timer(self, timer_dict):  # 通过计时器字典映射生成对应的计时器
        self.public_timer_dict = {}
        for key, value in timer_dict.items():
            group = BaseGroup()
            timer = CycleTimer(value)
            self.public_timer_dict[key] = [timer, group]

    def add_public_timer(self, timer_frame, tymer_name):  # 通过计时器和名字添加计时器
        if tymer_name in self.public_timer_dict.keys():
            return
        group = BaseGroup()
        timer = CycleTimer(timer_frame)
        self.public_timer_dict[tymer_name] = [timer, group]

    def add_sprite_to_public_timer(self, timer_name, *sprites):  # 添加精灵块到对应的计时器组
        for sprite in sprites:
            self.public_timer_dict[timer_name][1].add(sprite)
            # 移出sprite中的计时器
            sprite.timer_arr.pop(0)

    def change_public_timer(self, timer_name, timer_frame):  # 改变某个计时器组的计时器
        if timer_name in self.public_timer_dict.keys():
            self.public_timer_dict[timer_name][0] = CycleTimer(timer_frame)

    def reload_layer(self):  # 快刀斩乱麻,重置layer绘制层(开销过大,不建议使用)
        # 通过all_sprites更新层级
        self.layer_draw_sprites = []
        for sprites in self.all_sprites:
            if sprites.is_show:
                self.layer_draw_sprites[sprites.layer].append(sprites)

    def reload_collision(self):  # 快刀斩乱麻,重置collision碰撞组(开销过大,不建议使用)
        self.collision_sprites.empty()
        for sprite in self.all_sprites:
            if sprite.is_collision:
                self.collision_sprites.add(sprite)

    def add_collision_sprites(self, *sprites):  # 将某些sprites添加到碰撞组
        for sprite in sprites:
            sprite.is_collision = True
            if not self.collision_sprites.has(sprite):
                self.collision_sprites.add(sprite)

    def add_click_able_sprites(self, *sprites):  # 将某些sprites添加到点击组
        for sprite in sprites:
            if not self.click_able_sprites.has(sprite):
                self.click_able_sprites.add(sprite)

    def drop_collision_sprites(self, *sprites):  # 从碰撞组删除某些sprites
        for sprite in sprites:
            if self.collision_sprites.has(sprite):
                self.collision_sprites.remove(sprite)

    def add_block(self, *blocks):  # 向所有管理的组中添加方块(建议更改块的种类,精简块的种类)
        for block in blocks:
            if self.all_sprites.has(block):
                continue
            block.add(self.all_sprites)
            self.layer_draw_sprites[block.layer].add(block)  # 对应的绘制层
            # 特殊存储碰撞组
            if block.is_collision:
                self.collision_sprites.add(block)
            # 特殊存储按钮组
            if block.type == Block_type.button:
                self.click_able_sprites.add(block)
            # 特殊处理存储画布
            if block.type == Block_type.panel:  # 当出现的是一个显式精灵组时
                self.focus_able_sprites.add(block)
                if block.is_show:
                    for inner_block in block.sprites_group.sprites():
                        if inner_block.type == Block_type.button:
                            self.click_able_sprites.add(inner_block)
                        elif inner_block.type == Block_type.panel:
                            for inner_block_inner_block in inner_block.sprites_group.sprites():
                                self.add_block(inner_block_inner_block)

    def all_draw(self, surf):  # 层级精灵组绘制
        # 通过已经排序了的层级精灵组绘制,提升运行速度
        for layer_sprites in self.layer_draw_sprites:
            for sprite in layer_sprites:
                if sprite.is_show:
                    sprite.draw(surf)

    def layer_draw(self, surf, layer):  # 单独绘制某个层级
        for sprite in self.layer_draw_sprites[layer]:
            sprite.draw(surf)

    def all_update(self):  # 对执行update方法
        # 对精灵执行update
        self.all_sprites.update()

        # 对自己维护的计时器组执行update方法
        for value in self.public_timer_dict.values():
            value[0].next_frame()
            if value[0].is_end:  # 计时完毕则更新该组的动画
                for sprite in value[1].sprites():
                    sprite.update_image_index(self)
                value[0].reset()

        # self.print_all_groups()

    def set_layer(self, sprite, aim_layer):  # 未检查是否有误
        # sprite.set_layer(aim_layer)
        # self.reload_layer()
        old_layer = sprite.layer
        self.layer_draw_sprites[old_layer].remove(sprite)
        self.layer_draw_sprites[aim_layer].add(sprite)

    def print_all_groups(self):  # 打印当前记录的精灵组信息
        print("all_sprites", self.all_sprites)
        print("layer_draw_sprites", self.layer_draw_sprites)
        print("collision_sprites", self.collision_sprites)
        print("click_able_sprites", self.click_able_sprites)
        print("focus_able_sprites", self.focus_able_sprites)
